/*
 * Date         Author      Note
 * 2015.04.13   wzwz        增加探针信号反馈
 * 2015.04.24   wzwz        增加辛克复位
 * 2015.05.20   wzwz        起底板错误反馈掩码
 * 2015.05.25   wzwz        起底板CAN通讯失败的处理
 * 2015.06.25   wzwz        修改卸片复位
 * 2015.07.01   wzwz        延长机头反馈的等待时间
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <mh/common.h>
#include <pthread.h>
#include "dualram.h"

#define SRAM_DEV_FILE         "/dev/dpram_idt7132"
#define DEBUG_OUT(format,...) printf(format,##__VA_ARGS__)
#define RECV_EXTRA_DATA(recv) { DEBUG_OUT("%s %d receive extra data: %02X, %02X, %02X, %02X\n", __FILE__, __LINE__, recv[0], recv[1], recv[2], recv[3]); }


/* knit complete,0编织没有开始，１编织中，２编织完成 */
#define KNIT_PREARE     (0x00 << 1)
#define KNITING         (0x01 << 1)
#define KNIT_COMPLETE   (0X01 << 2)

#define LOOP_KC_BIT         (0x03 << 1)
/* side yarn */
#define LOOP_SY_BIT         (0x01 << 3)
/* yarn carrier */
#define LOOP_YC_BIT         (0x01 << 4)
/* need loop bit */
#define LOOP_NL_BIT         (0x01 << 5)
/* is front refused yarn */
#define LOOP_FRY_BIT        (0x01 << 6)
/* is back refused yarn */
#define LOOP_BRY_BIT        (0x01 << 7)



enum {
    RESET_FINISHED = 1,
};

enum {IO_TYPE_NONE, IO_TYPE_READ, IO_TYPE_WRITE, IO_TYPE_DECP, IO_TYPE_ICID,
    IO_TYPE_PRODUCT
};

enum {
    SEND_BASE_BIT = 0,
    SEND_CAM_BIT = 0x00000001,
    SEND_KNIT_CONTINUE_BIT = 0x00000002,
};

typedef struct {
    int fd_ram;
    int dualram_io_type;
    pthread_mutex_t udp_mutex;
    DUALRAM_TYPE dualram_type;
}MACHINE, *PMACHINE;

/*
 * init machine object
 * param cam: cams of system, from 1 to 4
 */
PMACHINE CreateSram(uchar cam)
{
    PMACHINE pmac = calloc(1, sizeof(MACHINE));
    if(pmac)
    {
        pmac->fd_ram = open(SRAM_DEV_FILE, O_RDWR);
        if(pmac->fd_ram < 0)
        {
            printf("Failed to open %s\n", SRAM_DEV_FILE);
            free(pmac);
            return NULL;
        }
        if(pthread_mutex_init(&pmac->udp_mutex, NULL))
        {
            printf("failed to init udp mutex\n");
            free(pmac);
            return NULL;
        }
        pmac->dualram_io_type = IO_TYPE_NONE;
        pmac->dualram_type = DUALRAM_MH_RUN;
    }
    return pmac;
}
/*
 * destroy machine object
 */
void DestroySram(PMACHINE pmac)
{
    if(pmac->fd_ram > -1)
    {
        close(pmac->fd_ram);
    }
    pthread_mutex_destroy(&pmac->udp_mutex);
}
/*
 *
 */
int SendData(PMACHINE pmac, uchar *pData, int size)
{
    int ret = 0;
    //int count = 0;
    if(pmac->fd_ram > -1)
    {
        if(pmac->dualram_io_type != IO_TYPE_WRITE)
        {
            pmac->dualram_io_type = IO_TYPE_WRITE;
            SET_ARM2DSP(pmac->fd_ram);
        }
        ret = write(pmac->fd_ram, pData, size);
        //printf("send: %d, %d\n", pData[0], pData[1]);
        if(ret <= 0)
        {
            return -1;
        }
        else
        {
            if(ret != size)
            {
                DEBUG_OUT("recv size is not valid:%d=%d\n", size, ret);
            }
            if(pData[0] == MH_RUN || pData[0] == MH_BACK)
            {
                pmac->dualram_type = DUALRAM_MH_RUN;
            }
            else
            {
                pmac->dualram_type = DUALRAM_MH_TEST;
            }
            return 0;
        }
    }
    return -2;
}
/*
 *
 */
int RecvData(PMACHINE pmac, uchar *pData, int size)
{
    int ret = 0;
    char buf[DSP2ARM_SIZE] = {0, 0, 0, 0};
    if(pmac->fd_ram > -1)
    {
        if(pmac->dualram_io_type != IO_TYPE_READ)
        {
            SET_DSP2ARM(pmac->fd_ram);
            pmac->dualram_io_type = IO_TYPE_READ;
        }
        ret = read(pmac->fd_ram, buf, DSP2ARM_SIZE);
        if(ret <= 0)
        {
            return -1;
        }
        else
        {
            if(ret != DSP2ARM_SIZE)
            {
                DEBUG_OUT("recv size is not valid:%d=%d\n", DSP2ARM_SIZE, ret);
            }
            if(pData)
            {
                memcpy(pData, buf, size);
            }
            return 0;
        }
    }
    return -2;
}



/*
 * all of below be which to send by machine
 * all be message of can which is command of yarn, selector...
 * all this send by can through machine
 */
/*
 * message of can sent by machine about selector
 * param item: 0-63
 */
int SramToggleSelect(PMACHINE pmac, uchar item, uchar state)
{
    uchar data[64] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_XZQ;
    data[2] = item;
    data[3] = state;
    int retry = 10;

    int ret = 0;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * reset select
 */
int SramResetSelect(PMACHINE pmac, uchar item)
{
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_RESET_XZQ;
    data[2] = item;
    data[3] = 0;
    int ret = 0;
    int retry = 10;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * message of can sent by machine about yarn
 * param item: 0-15
 */
int SramToggleYarn(PMACHINE pmac, uchar item, uchar state)
{
    uchar data[4] = {0};
    uchar recv[32] = {0};
    int retry = 10;
    int ret = 0;
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_YARN;
    data[2] = (item + 8) & 0x0F;
    data[3] = state;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * reset yarn
 */
int SramResetYarn(PMACHINE pmac, uchar item)
{
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_RESET_YARN;
    data[2] = item;
    data[3] = 0;
    int ret = 0;
    int retry = 10;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * message of can sent by machine about cam
 */
int SramToggleCam(PMACHINE pmac, uchar item, uchar state)
{
    uchar data[4] = {0};
    uchar recv[32] = { 0 };
    int retry = 10;
    int ret = 0;
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_SJDCT;
    data[2] = item;
    data[3] = state;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * reset cam
 */
int SramResetCam(PMACHINE pmac, uchar item)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_RESET_CAM;
    data[2] = item;
    data[3] = 0;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * message of can sent by machine about stitch
 */
int SramToggleStitch(PMACHINE pmac, uchar item, short state)
{
    int retry = 10;
    int ret = 0;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_DUMU;
    data[2] = item;
    data[3] = state;
    data[4] = state >> 8;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * message of can sent by machine about stitch
 */
int SramToggleSink(PMACHINE pmac, uchar item, short state)
{
    int retry = 10;
    int ret = 0;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_SINK;
    data[2] = item;
    data[3] = state;
    data[4] = state >> 8;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * get feedback of machine head
 */
int SramGetHeaderFeedback(PMACHINE pmac, int *feedback)
{
    int ret = 0;
    int retry = 100;
    uchar recv[32] = {0};
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = RecvData(pmac, recv, sizeof(recv));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0 || recv[0] != MH_SIGN_JITOU)
    {
        if(retry-- > 0)
        {
            usleep(2000);
            goto RETRY;
        }
        ret = -1;
    }
    else
    {
        memcpy(feedback, &recv[10], sizeof(int));
    }
    return ret;
}
/*
 * get state of header for running
 */
int SramGetHeaderState(PMACHINE pmac, uchar *recv, int size)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    data[0] = MH_TEST_GETPARAM;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, size))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            goto RETRY1;
        }
        goto END;
    }
    usleep(10000);
    retry = 30;
RETRY2:
    ret = RecvData(pmac, recv, size);
    if(ret < 0 || recv[0] != MH_TEST_GETPARAM || recv[1] != MH_TEST_SIGN)
    {
        if(retry-- > 0)
        {
            usleep(2000);
            goto RETRY2;
        }
        ret = -1;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}

enum {
    BUZZEL_DEV = 0,
    GREEN_LIGHT = 1,
    YELLOW_LIGHT = 2,
    RED_LIGHT = 3,
};
/*
 * turn off/on green light
 * \param state: 0-off, 1-on
 */
int SramSwitchGreenLight(PMACHINE pmac, int state)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_LED;
    data[2] = GREEN_LIGHT;
    data[3] = state;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(10000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * turn off/on yellow light
 * \param state: 0-off, 1-on
 */
int SramSwitchYellowLight(PMACHINE pmac, int state)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_LED;
    data[2] = YELLOW_LIGHT;
    data[3] = state;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(10000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * turn off/on red light
 * \param state: 0-off, 1-on
 */
int SramSwitchRedLight(PMACHINE pmac, int state)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_LED;
    data[2] = RED_LIGHT;
    data[3] = state;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(10000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * turn off/on buzzer
 * \param state: 0-off, 1-on
 */
int SramSwitchBuzzer(PMACHINE pmac, int state)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_LED;
    data[2] = BUZZEL_DEV;
    data[3] = state;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
* enable/disable driver of machine
* \param state: 0-disable, 1-enable(lock)
*/
int SramSwitchMacDriver(int state)
{
    return -1;
}
/*
 * run the machine
 * \param drt: 0-stop, 1-left, 2-right
 * \param speed: between 1-100
 */
int SramRunMotor(PMACHINE pmac, int drt, int speed)
{
    int ret = 0;
    int retry = 10;
    enum {
        MAC_LEFT = 1,
        MAC_RIGHT = 2,
        MAC_STOP = 3,
    };
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_JITOU;
    if(!drt)
    {
        data[2] = MAC_STOP;
    }
    else
    {
        data[2] = drt;
    }
    data[3] = speed;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
* run the master rab or high roller
* \param speed: 0-stop, <0-reversal open, >0 normal run
*/
int SramRunRab(PMACHINE pmac, int speed)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_GLL;
    data[2] = speed;
    data[3] = speed >> 8;
    data[4] = speed >> 16;
    data[5] = speed >> 24;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(10000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * run the auxiliary rab or low roller
 * \param speed: 0-stop, <0-reversal open, >0 normal run
 */
int SramRunRoller(PMACHINE pmac, int speed)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_ROLL;
    data[2] = speed;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 *
 */
int SramRunFeeder(PMACHINE pmac, int l0r1, uchar speed)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = l0r1 ? TEST_SONGSHA_RIGHT : TEST_SONGSHA_LEFT;
    data[2] = speed;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(2000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * run rock
 */
int SramRunRock(PMACHINE pmac, short pos, uchar speed, int zero_com)
{
    int ret = 0;
    int retry = 30;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    data[1] = TEST_ROCK;
    data[2] = pos;
    data[3] = pos >> 8;
    data[4] = speed;
    if(!pos)
    {
        data[5] = zero_com;
        data[6] = zero_com >> 8;
        data[7] = zero_com >> 16;
        data[8] = zero_com >> 24;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    else
    {
        printf("SramRunRock: %d\n", pos);
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(2000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * set state of machine
 * param state: test/run
 */
int SramSendState(PMACHINE pmac, int state)
{
    int ret = 0;
    int retry = 30;
    //printf("sram_state: %d, %d\n", state, pmac->dualram_type);
    if(state != SYS_STATE_KNIT)
    {
        return 0;
    }
    if(pmac->dualram_type == DUALRAM_MH_RUN)
    {
        return 0;
    }
    uchar data[4] = {0};
    data[0] = MH_BACK;
    uchar recv[32] = {0};
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    else
    {
        //printf("SramSendState: %d\n", data[0]);
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            usleep(10000);
            goto RETRY;
        }
    }

    return ret;
}
/*
 * run the yarn feeder machine
 * \param drt: 0-left, 1-right
 * \param state: 0-off, 1-on
 */
int SramSwitchYarnFeeder(PMACHINE pmac, int drt, int state)
{
    int ret = 0;
    int retry = 10;
    uchar data[32] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_JIJIA;
    if(drt)
    {
        data[1] = TEST_SONGSHA_RIGHT;
    }
    else
    {
        data[1] = TEST_SONGSHA_LEFT;
    }
    data[2] = state;
    data[3] = state;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * get signal of rack om machine
 */
int SramGetRackSignal(PMACHINE pmac, uchar *signal, int size, short *pulse)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_XHFK;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            goto RETRY1;
        }
        goto END;
    }
    usleep(10000);
    retry = 10;
RETRY2:
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0 || recv[0] != MH_SIGN_JIJIA)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
    else
    {
        signal[0] = recv[2];
        signal[1] = recv[3];
        signal[2] = recv[4];
        signal[3] = recv[5];
        signal[4] = recv[6];
        signal[5] = recv[7];
        //probe
        signal[5] |= recv[11] & 0x60;
        //needle
        int *src = (int*)&recv[16];
        *pulse = *src;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * get needle of motor on machine
 */
int SramGetCurrentPulse(PMACHINE pmac, int *pulse)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_XHFK;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            goto RETRY1;
        }
        goto END;
    }
    usleep(10000);
    retry = 10;
RETRY2:
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0 || recv[0] != MH_SIGN_JIJIA)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
    else
    {
        *pulse = *((int*)&recv[16]);
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramGetRunFeedback(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = RecvData(pmac, data, size);
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(!ret)
    {
        if(data[5] & 1)
        {
            int checksum1 = 0;
            checksum1 += data[14]; //RUN_STATE
            checksum1 += data[4]; //D2A_BARSTATE
            checksum1 += data[18] + (data[18 + 1] << 8); //NEEDLE_NUM
            checksum1 += data[6]; //RUN_DIR
            checksum1 += data[2]; //D2A_ERRCODE
            checksum1 += data[3]; //D2A_DUMUERROR

            int checksum2 = data[17] & 0xFF;
            checksum2 <<= 8;
            checksum2 |= data[16] & 0xFF; //D2A_CHECKSUM
            checksum1 &= 0xFFFF;
            checksum2 &= 0xFFFF;
            //DEBUG_OUT("checksum: %d, %d\n", checksum1, checksum2);
            if(data[0] != 'F' || data[1] != 'B' || checksum1 != checksum2)
            {
                ret = -1;
            }
        }
        else
        {
            uchar check = data[2] ^ data[3] ^ data[6] ^ data[14] ^ data[18] ^ data[19];
            if(data[0] != 'F' || data[1] != 'B' || data[17] != check)
            {
                ret = -1;
            }
        }
    }
    return ret;
}
/*
 * send data
 */
int SramSendKnitData(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    data[0] = MH_RUN;
    data[1] = MH_RUN_NORMAL;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, size);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * send data
 */
int SramRetrySendKnitData(PMACHINE pmac, uchar *data, int size, int retry_times)
{
    int ret = 0;
    uchar recv[32] = {0};
    data[0] = MH_RUN;
    data[1] = MH_RUN_NORMAL;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, size);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(retry_times-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * start machine
 */
enum {
    SRAM_RESET_START = 0,
    SRAM_RESET_GOTO = 1,
    SRAM_RESET_DROP = 2,
};
int SramStartMachine(PMACHINE pmac, uchar *data, int size, int type)
{
    int ret = 0;
    int retry = 10;
    uchar recv[32] = {0};
    data[0] = MH_RUN;
    if(type == SRAM_RESET_GOTO)
    {
        data[1] = MH_RUN_SETBEGIN;
    }
    else if(type == SRAM_RESET_DROP)
    {
        data[1] = MH_RUN_DROPCLOTH;
    }
    else
    {
        data[1] = MH_RUN_RESET;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, size);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramSendContinueData(PMACHINE pmac, uchar *data, uint size)
{
    int ret = 0;
    int retry = 10;
    uchar recv[32] = {0};
    data[0] = MH_RUN;
    data[1] = MH_RUN_GOONKNIT;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, size);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramSendSysData(PMACHINE pmac, uchar *data, int size, int mask)
{
    uchar recv[32] = {0};
    int ret = 0;
    int retry = 10;
    data[0] = MH_TEST_SETPARAM;
    data[1] = MH_TEST_SETSIGN;
    if(mask & SEND_CAM_BIT)
    {
        data[1] |= MH_TEST_SETCAM;
    }
    if(mask & SEND_KNIT_CONTINUE_BIT)
    {
        data[1] |= MH_TEST_CONTINUEKNIT;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, __min(size, ARM2DSP_SIZE));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
    }
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(retry-- > 0)
        {
            usleep(10000);
            goto RETRY;
        }
    }
    return ret;
}
/*
 * get version info
 */
int SramGetVersionInfo(PMACHINE pmac, VERSION *pversion)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_GET_VERSION;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY1;
        }
        goto END;
    }
    usleep(10000);
    retry = 10;
RETRY2:
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0 || recv[0] != MH_GET_VERSION || recv[1] != MH_TEST_SIGN)
    {
        if(retry-- > 0)
        {
            usleep(10000);
            goto RETRY2;
        }
        ret = -1;
    }
    else
    {
        pversion->header[0] = recv[3];
        pversion->header[1] = recv[2];
        pversion->header[2] = recv[13];
        pversion->header[3] = recv[12];

        pversion->rack[0] = recv[5];
        pversion->rack[1] = recv[4];
        pversion->rack[2] = recv[17];
        pversion->rack[3] = recv[16];

        pversion->board[0] = recv[9];
        pversion->board[1] = recv[8];
        pversion->board[2] = recv[15];
        pversion->board[3] = recv[14];

        pversion->csk[0] = recv[11];
        pversion->csk[1] = recv[10];
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * get data from I2C
 */
int SramGetPayment(PMACHINE pmac, uchar *recv, int size)
{
    uchar data[6] = {0};
    int retry = 10;
    int ret = 0;
    data[0] = MH_TEST_I2C_READ;
    data[1] = 1;
    data[2] = 0;
    data[3] = 0;
    data[4] = size - 2;
    data[5] = 0;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, size))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            goto RETRY1;
        }
        goto END;
    }
    retry = 50;
RETRY2:
    usleep(20000);
    ret = RecvData(pmac, recv, size);
    if(ret < 0 || recv[0] != MH_TEST_I2C_READ || recv[1] != 0)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set data to I2C
 */
int SramSetPayment(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    int retry = 10;
    uchar recv[32] = {0};
    data[0] = MH_TEST_I2C_SAVE;
    data[1] = 1;
    data[2] = 16;
    data[3] = 0;
    data[4] = size -6;
    data[5] = 0;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, size);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            goto RETRY1;
        }
        goto END;
    }
    retry = 50;
RETRY2:
    usleep(20000);
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
    else
    {
        //printf("Write I2C ret %d\n", recv[1]);
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramUpdateRack(PMACHINE pmac)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = { 0 };
    data[0] = MH_TEST_DSP;
    data[1] = TEST_DSP2812_UPDATE;
    data[2] = data[0] ^ data[1];
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        uchar recv[32] = { 0 };
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    else
    {
        /* 等待2812复位完成 */
        usleep(200000);
    }
    return ret;
}
/*
 *
 */
int SramGetPowerOff(PMACHINE pmac, uchar *recv, uint size)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    data[0] = MH_TEST_GETGOON;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, size))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY1;
        }
        goto END;
    }
    retry = 20;
RETRY2:
    usleep(1000);
    ret = RecvData(pmac, recv, size);
    if(ret < 0 || recv[0] != MH_TEST_GETGOON || recv[1] != MH_TEST_SIGN || recv[2] != 0xBB || recv[3] != 0xF0)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramGetPowerOffExtra(PMACHINE pmac, uchar *recv, uint size)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    data[0] = MH_TEST_GETPARAM;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, size))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY1;
        }
        goto END;
    }
    retry = 20;
RETRY2:
    usleep(1000);
    ret = RecvData(pmac, recv, size);
    if(ret < 0 || recv[0] != MH_TEST_GETPARAM || recv[1] != MH_TEST_SIGN)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramGetBoardFeedback(PMACHINE pmac, PBOARD_FEEDBACK pfeedback)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_BOARDFK;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY1;
        }
        goto END;
    }
    retry = 20;
RETRY2:
    usleep(1000);
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0 || recv[0] != MH_SIGN_BOARD)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
    else if(recv[13] & 0x80)
    {
        pfeedback->can_error = TRUE;
    }
    else
    {
        typedef struct {
            uint hook_act : 1;
            uint rsvd1 : 1;
            uint board_sj : 1;
            uint kaihe : 1;
            uint cs_error : 4;

            uint rsvd3 : 1;
            uint hook_open : 1;
            uint rab_open : 1;
            uint clip2 : 1;
            uint board_zero : 1;
            uint rab_close : 1;
            uint clip4 : 1;
            uint scissor1 : 1;

            uint rsvd4 : 1;
            uint hook_close : 1;
            uint rsvd5 : 1;
            uint clip3 : 1;
            uint board_safe : 1;
            uint board_high : 1;
            uint scissor2 : 1;
            uint clip1 : 1;

            uint rsvd6 : 8;
        }BOARD_FK;
        BOARD_FK *pboard;
        pboard = (void*)&recv[20];
        pfeedback->clip1 = !pboard->clip1;
        pfeedback->clip2 = !pboard->clip2;
        pfeedback->clip3 = !pboard->clip3;
        pfeedback->clip4 = !pboard->clip4;
        pfeedback->scissor1 = !pboard->scissor1;
        pfeedback->scissor2 = !pboard->scissor2;
        pfeedback->hook_open = !pboard->hook_open;
        pfeedback->hook_close = !pboard->hook_close;
        pfeedback->rab_open = !pboard->rab_open;
        pfeedback->rab_close = !pboard->rab_close;
        pfeedback->board_zero = !pboard->board_zero;
        pfeedback->board_safe = !pboard->board_safe;
        pfeedback->board_high = !pboard->board_high;
        pfeedback->kaihe = !pboard->kaihe;
        pfeedback->roll_open = (recv[5] & 0x20) ? TRUE : FALSE;
        //
        pfeedback->can_error = (recv[13] & 0x80) ? TRUE : FALSE;
        pfeedback->cs_error = pboard->cs_error;
        pfeedback->hook_act = pboard->hook_act;
        pfeedback->board_sj = pboard->board_sj;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramGetBoardCoder(PMACHINE pmac, short *pcoder)
{
    int ret = 0;
    int retry = 10;
    uchar data[4] = {0};
    uchar recv[32] = {0};
    data[0] = MH_BOARDCOUNTERFK;
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY1;
        }
        goto END;
    }
    retry = 20;
RETRY2:
    usleep(1000);
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0 || MH_BOARDCOUNTERFK != recv[0])
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
    else
    {
        *pcoder = (recv[24] << 8) | recv[23];
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramClipOff(PMACHINE pmac, int bits)
{
    int ret = 0;
    int retry = 10;
    uchar data[16] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_BOARD;
    data[1] = TEST_JZJD;
    if(bits & 0x01)
    {
        data[7] = 0x3F;
        data[8] = 0xFF;
    }
    else if(bits & 0x02)
    {
        data[3] = 0x3F;
        data[4] = 0xFF;
    }
    else if(bits & 0x04)
    {
        data[5] = 0x3F;
        data[6] = 0xFF;
    }
    else if(bits & 0x08)
    {
        data[12] = 0x3F;
        data[13] = 0xFF;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramClipOn(PMACHINE pmac, int bits)
{
    int ret = 0;
    int retry = 10;
    uchar data[16] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_BOARD;
    data[1] = TEST_JZJD;
    if(bits & 0x01)
    {
        data[7] = 0x7F;
        data[8] = 0xFF;
    }
    else if(bits & 0x02)
    {
        data[3] = 0x7F;
        data[4] = 0xFF;
    }
    else if(bits & 0x04)
    {
        data[5] = 0x7F;
        data[6] = 0xFF;
    }
    else if(bits & 0x08)
    {
        data[12] = 0x7F;
        data[13] = 0xFF;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramScissor(PMACHINE pmac, int bits)
{
    int ret = 0;
    int retry = 10;
    uchar data[16] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_BOARD;
    data[1] = TEST_JZJD;
    if(bits & 0x01)
    {
        data[2] = 0xFF;
        data[9] = 0x6F;
    }
    else if(bits & 0x02)
    {
        data[10] = 0x6F;
        data[11] = 0xFF;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramHook(PMACHINE pmac, int open)
{
    int ret = 0;
    int retry = 10;
    uchar data[16] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_BOARD;
    data[1] = TEST_QDBGZ;
    if(open)
    {
        data[2] = 0xC0;
    }
    else
    {
        data[2] = 0x40;
    }
    data[3] = 0x3C;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramBoardAct(PMACHINE pmac, int item, uchar speed)
{
    int ret = 0;
    int retry = 10;
    uchar data[16] = {0};
    uchar recv[32] = {0};
    data[0] = MH_TEST_BOARD;
    data[1] = TEST_QDBSJ;
    switch(item)
    {
    case -3://step down
        data[2] = 0x10;
        data[3] = 50;
        data[4] = 0xFF;
        data[5] = 0xFF;
        data[6] = -4;
        data[7] = 0xFF;
        break;
    case -2://relax
        data[2] = 0x0F;
        data[3] = 0;
        break;
    case -1://down
        data[2] = 0x10;
        data[3] = speed;
        break;
    case 0://stop
        data[2] = 0;
        data[3] = 0;
        break;
    case 1://up
        data[2] = 0x30;
        data[3] = speed;
        break;
    case 2://safe
        data[2] = 0x20;
        data[3] = speed;
        break;
    case 3://step up
        data[2] = 0x30;
        data[3] = 50;
        data[4] = 0xFF;
        data[5] = 0xFF;
        data[6] = 4;
        data[7] = 0;
        break;
    default:
        break;
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, sizeof(data));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY;
        }
    }
    return ret;
}
/*
 *
 */
int SramResetKnitSink(PMACHINE pmac, int f0b1, short value)
{
    int ret = 0;
    int retry = 10;
    uchar recv[32] = {0};
    uchar data[64] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_DUMU_RESTORE;
    short *p = (short *)&data[2];
    if(f0b1)
    {
        data[22 + 9] = TRUE;
        p[9] = value;
    }
    else
    {
        data[22 + 4] = TRUE;
        p[4] = value;
    }
    pthread_mutex_lock(&pmac->udp_mutex);
RETRY1:
    ret = SendData(pmac, data, sizeof(data));
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY1;
        }
        goto END;
    }
    retry = 20;
RETRY2:
    usleep(10000);
    ret = RecvData(pmac, recv, sizeof(recv));
    if(ret < 0 || recv[0] != MH_SIGN_JITOU)
    {
        if(retry-- > 0)
        {
            goto RETRY2;
        }
        ret = -1;
    }
END:
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 *
 */
int SramRestoreDumuAndSink(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    int retry = 10;
    uchar recv[32] = {0};
    data[0] = MH_TEST_JITOU;
    data[1] = TEST_DUMU_RESTORE;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = SendData(pmac, data, size);
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(!RecvData(pmac, recv, sizeof(recv)))
        {
            RECV_EXTRA_DATA(recv);
        }
        if(retry-- > 0)
        {
            usleep(1000);
            goto RETRY;
        }
    }
    return ret;
}
